using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ConsentManagementProviderLib;
using Newtonsoft.Json;
using UnityEngine;
using Voodoo.Sauce.Core;
using Voodoo.Sauce.Core.Model;
using Voodoo.Sauce.Internal;
using Voodoo.Sauce.Privacy.UI;

namespace Voodoo.Sauce.Privacy.Sourcepoint
{
	public class Sourcepoint : IConsentManagementProvider
	{
		private enum Purpose
		{
			Age = 0,
			StoreAndAccessInformationOnDevice = 1,
			SelectBasicAds = 2,
			CreatePersonalisedAdsProfile = 3,
			SelectPersonalisedAds = 4,
			CreatePersonalisedContentProfile = 5,
			SelectPersonalisedContent = 6,
			MeasureAdsPerformance = 7,
			MeasureContentPerformance = 8,
			ApplyMarketResearchToGenerateAudienceInsights = 9,
			DevelopAndImproveProducts = 10
		}

		private const string TAG = "Sourcepoint";

		private Dictionary<string, Purpose> _keyPurposeDictionary;

		private List<CAMPAIGN_TYPE> _allCampaignTypesToLoad = new List<CAMPAIGN_TYPE> { CAMPAIGN_TYPE.GDPR };

		private MESSAGE_LANGUAGE _language = MESSAGE_LANGUAGE.ENGLISH;

		private CAMPAIGN_ENV _campaignEnvironment = CAMPAIGN_ENV.PUBLIC;

		private Action _onConsentUIReady;

		private Action<CONSENT_ACTION_TYPE> _onConsentAction;

		private Action<Exception> _onConsentError;

		private Action _onConsentUIFinished;

		private Action<SpConsents> _onConsentReady;

		private Action<bool> _onPrivacyShown;

		private SourcepointBehaviour _sourcepointBehaviour;

		private GdprConsent _gdprConsent;

		private Dictionary<Purpose, bool> _purposeConsentDictionary;

		private int _accountId;

		private int _propertyId;

		private int _privacyManagerId;

		private string _propertyName;

		private long _messageTimeoutInSeconds;

		private string _authId;

		private bool _isInitialized;

		public string GetName()
		{
			return "Sourcepoint";
		}

		async Task<CmpConsent> IConsentManagementProvider.GetConsent(Action<bool> onPrivacyShown)
		{
			if (!_isInitialized)
			{
				Initialize(onPrivacyShown);
			}
			return await AskConsent();
		}

		async Task<CmpConsent> IConsentManagementProvider.OpenPrivacySettings()
		{
			return await ShowPrivacyScreen(delegate
			{
				CMP.LoadPrivacyManager(CAMPAIGN_TYPE.GDPR, _privacyManagerId.ToString(), PRIVACY_MANAGER_TAB.DEFAULT);
			});
		}

		private void Initialize(Action<bool> onPrivacyShown)
		{
			_onConsentUIReady = (Action)Delegate.Combine(_onConsentUIReady, new Action(OnConsentUIReadyDebugLog));
			_onConsentAction = (Action<CONSENT_ACTION_TYPE>)Delegate.Combine(_onConsentAction, new Action<CONSENT_ACTION_TYPE>(OnConsentActionDebugLog));
			_onConsentError = (Action<Exception>)Delegate.Combine(_onConsentError, new Action<Exception>(OnConsentErrorDebugLog));
			_onConsentUIFinished = (Action)Delegate.Combine(_onConsentUIFinished, new Action(OnConsentUIFinishedDebugLog));
			_onConsentReady = (Action<SpConsents>)Delegate.Combine(_onConsentReady, new Action<SpConsents>(OnConsentReadyDebugLog));
			_onPrivacyShown = onPrivacyShown;
			SetConfiguration(VoodooSettings.Load().SourcepointConfiguration);
			InstantiateBehaviour();
			InitializeCMP();
			_isInitialized = true;
		}

		private async Task<CmpConsent> AskConsent()
		{
			return await ShowPrivacyScreen(delegate
			{
				CMP.LoadMessage(_authId);
			});
		}

		private async Task<CmpConsent> ShowPrivacyScreen(Action openPrivacyScreen)
		{
			VoodooLog.LogDebug(Module.PRIVACY, "Sourcepoint", "Sourcepoint.ShowPrivacyScreen");
			bool waitUserConsent = true;
			bool consentUpdated = false;
			CmpConsent cmpConsent = new CmpConsent();
			Action<SpConsents> onConsentReady = delegate(SpConsents spConsents)
			{
				VoodooLog.LogDebug(Module.PRIVACY, "Sourcepoint", "Sourcepoint.ShowPrivacyScreen.OnConsentReady: spConsents: " + JsonConvert.SerializeObject(spConsents));
				_gdprConsent = spConsents.gdpr.consents;
				_purposeConsentDictionary = GetPurposeConsents(_gdprConsent);
				VoodooLog.LogDebug(Module.PRIVACY, "Sourcepoint", "Sourcepoint.ShowPrivacyScreen.OnConsentReady: purposeConsentDictionary: " + JsonConvert.SerializeObject(_purposeConsentDictionary));
				cmpConsent.privacyConsent = GetPrivacyConsent(_purposeConsentDictionary);
				waitUserConsent = false;
			};
			Action onConsentUIReady = delegate
			{
				_onPrivacyShown?.Invoke(obj: true);
				consentUpdated = true;
			};
			Action<Exception> onConsentError = delegate
			{
				waitUserConsent = false;
			};
			_onConsentReady = (Action<SpConsents>)Delegate.Combine(_onConsentReady, onConsentReady);
			_onConsentUIReady = (Action)Delegate.Combine(_onConsentUIReady, onConsentUIReady);
			_onConsentError = (Action<Exception>)Delegate.Combine(_onConsentError, onConsentError);
			openPrivacyScreen();
			while (waitUserConsent)
			{
				await Task.Yield();
			}
			_onConsentReady = (Action<SpConsents>)Delegate.Remove(_onConsentReady, onConsentReady);
			_onConsentUIReady = (Action)Delegate.Remove(_onConsentUIReady, onConsentUIReady);
			_onConsentError = (Action<Exception>)Delegate.Remove(_onConsentError, onConsentError);
			if (consentUpdated)
			{
				_onPrivacyShown?.Invoke(obj: false);
				TrackConsentUpdate(_purposeConsentDictionary);
			}
			cmpConsent.consentUpdated = consentUpdated;
			VoodooLog.LogDebug(Module.PRIVACY, "Sourcepoint", "Sourcepoint.ShowPrivacyScreen.OnConsentReady: privacyConsent: " + JsonConvert.SerializeObject(cmpConsent));
			return cmpConsent;
		}

		private void SetConfiguration(SourcepointConfiguration configuration)
		{
			_accountId = configuration.accountId;
			_propertyId = configuration.propertyId;
			_privacyManagerId = configuration.privacyManagerId;
			_propertyName = configuration.propertyName;
			_messageTimeoutInSeconds = configuration.messageTimeoutInSeconds;
			_authId = ((configuration.authId != "") ? configuration.authId : null);
			_keyPurposeDictionary = new Dictionary<string, Purpose>
			{
				{
					configuration.ageKey,
					Purpose.Age
				},
				{
					configuration.storeAndAccessInformationOnDeviceKey,
					Purpose.StoreAndAccessInformationOnDevice
				},
				{
					configuration.selectBasicAdsKey,
					Purpose.SelectBasicAds
				},
				{
					configuration.createPersonalisedAdsProfileKey,
					Purpose.CreatePersonalisedAdsProfile
				},
				{
					configuration.selectPersonalisedAdsKey,
					Purpose.SelectPersonalisedAds
				},
				{
					configuration.createPersonalisedContentProfileKey,
					Purpose.CreatePersonalisedContentProfile
				},
				{
					configuration.selectPersonalisedContentKey,
					Purpose.SelectPersonalisedContent
				},
				{
					configuration.measureAdsPerformanceKey,
					Purpose.MeasureAdsPerformance
				},
				{
					configuration.measureContentPerformanceKey,
					Purpose.MeasureContentPerformance
				},
				{
					configuration.applyMarketResearchToGenerateAudienceInsightsKey,
					Purpose.ApplyMarketResearchToGenerateAudienceInsights
				},
				{
					configuration.developAndImproveProductsKey,
					Purpose.DevelopAndImproveProducts
				}
			};
		}

		private void InstantiateBehaviour()
		{
			if (!(_sourcepointBehaviour != null))
			{
				GameObject gameObject = new GameObject();
				gameObject.name = "SourcepointBehaviour";
				_sourcepointBehaviour = gameObject.AddComponent<SourcepointBehaviour>();
				SourcepointBehaviour.SourcepointBehaviourParameters parameters = new SourcepointBehaviour.SourcepointBehaviourParameters
				{
					onConsentUIReady = delegate
					{
						_onConsentUIReady();
					},
					onConsentAction = delegate(CONSENT_ACTION_TYPE consent)
					{
						_onConsentAction(consent);
					},
					onConsentError = delegate(Exception error)
					{
						_onConsentError(error);
					},
					onConsentUIFinished = delegate
					{
						_onConsentUIFinished();
					},
					onConsentReady = delegate(SpConsents consent)
					{
						_onConsentReady(consent);
					}
				};
				_sourcepointBehaviour.Initialize(parameters);
			}
		}

		private void InitializeCMP()
		{
			if (!Enum.TryParse<MESSAGE_LANGUAGE>(Application.systemLanguage.ToString(), ignoreCase: true, out _language))
			{
				_language = MESSAGE_LANGUAGE.ENGLISH;
			}
			List<SpCampaign> list = new List<SpCampaign>();
			if (_allCampaignTypesToLoad.Contains(CAMPAIGN_TYPE.GDPR))
			{
				List<TargetingParam> targetingParams = new List<TargetingParam>
				{
					new TargetingParam("location", "EU")
				};
				SpCampaign item = new SpCampaign(CAMPAIGN_TYPE.GDPR, targetingParams);
				list.Add(item);
			}
			CMP.Initialize(list, _accountId, _propertyId, _propertyName, _language, _campaignEnvironment, _messageTimeoutInSeconds);
		}

		private Dictionary<Purpose, bool> GetPurposeConsents(GdprConsent gdprConsent)
		{
			Dictionary<Purpose, bool> dictionary = new Dictionary<Purpose, bool>
			{
				{
					Purpose.Age,
					true
				},
				{
					Purpose.StoreAndAccessInformationOnDevice,
					true
				},
				{
					Purpose.SelectBasicAds,
					true
				},
				{
					Purpose.CreatePersonalisedAdsProfile,
					true
				},
				{
					Purpose.SelectPersonalisedAds,
					true
				},
				{
					Purpose.CreatePersonalisedContentProfile,
					true
				},
				{
					Purpose.SelectPersonalisedContent,
					true
				},
				{
					Purpose.MeasureAdsPerformance,
					true
				},
				{
					Purpose.MeasureContentPerformance,
					true
				},
				{
					Purpose.ApplyMarketResearchToGenerateAudienceInsights,
					true
				},
				{
					Purpose.DevelopAndImproveProducts,
					true
				}
			};
			foreach (KeyValuePair<string, SpVendorGrant> grant in gdprConsent.grants)
			{
				foreach (KeyValuePair<string, bool> purposeGrant in grant.Value.purposeGrants)
				{
					if (!purposeGrant.Value && _keyPurposeDictionary.TryGetValue(purposeGrant.Key, out var value))
					{
						dictionary[value] = purposeGrant.Value;
					}
				}
			}
			return dictionary;
		}

		private PrivacyConsent GetPrivacyConsent(Dictionary<Purpose, bool> purposeConsentDictionary)
		{
			return new PrivacyConsent
			{
				isSixteenOrOlder = purposeConsentDictionary[Purpose.Age],
				adsConsent = (purposeConsentDictionary[Purpose.StoreAndAccessInformationOnDevice] && purposeConsentDictionary[Purpose.SelectBasicAds] && purposeConsentDictionary[Purpose.CreatePersonalisedAdsProfile] && purposeConsentDictionary[Purpose.SelectPersonalisedAds] && purposeConsentDictionary[Purpose.CreatePersonalisedContentProfile] && purposeConsentDictionary[Purpose.SelectPersonalisedContent]),
				analyticsConsent = (purposeConsentDictionary[Purpose.StoreAndAccessInformationOnDevice] && purposeConsentDictionary[Purpose.MeasureAdsPerformance] && purposeConsentDictionary[Purpose.MeasureContentPerformance] && purposeConsentDictionary[Purpose.ApplyMarketResearchToGenerateAudienceInsights] && purposeConsentDictionary[Purpose.DevelopAndImproveProducts])
			};
		}

		private void TrackConsentUpdate(Dictionary<Purpose, bool> purposeConsentDictionary)
		{
			Dictionary<string, object> dictionary = new Dictionary<string, object>();
			foreach (KeyValuePair<Purpose, bool> item in purposeConsentDictionary)
			{
				dictionary.Add(item.Key.ToString(), item.Value);
			}
			string text = JsonConvert.SerializeObject(dictionary);
			VoodooLog.LogDebug(Module.PRIVACY, "Sourcepoint", "Sourcepoint.TrackConsentUpdate: " + text);
		}

		private void OnConsentUIReadyDebugLog()
		{
			VoodooLog.LogDebug(Module.PRIVACY, "Sourcepoint", "Sourcepoint.OnConsentUIReady");
		}

		private void OnConsentActionDebugLog(CONSENT_ACTION_TYPE action)
		{
			VoodooLog.LogDebug(Module.PRIVACY, "Sourcepoint", $"Sourcepoint.OnConsentAction: {action}");
		}

		private void OnConsentErrorDebugLog(Exception exception)
		{
			VoodooLog.LogDebug(Module.PRIVACY, "Sourcepoint", $"Sourcepoint.OnConsentError: {exception}");
		}

		private void OnConsentUIFinishedDebugLog()
		{
			VoodooLog.LogDebug(Module.PRIVACY, "Sourcepoint", "Sourcepoint.OnConsentUIFinished");
		}

		private void OnConsentReadyDebugLog(SpConsents consents)
		{
			VoodooLog.LogDebug(Module.PRIVACY, "Sourcepoint", "Sourcepoint.OnConsentReady: " + JsonConvert.SerializeObject(consents));
		}
	}
}
